package cn.tqfeiyang.smartadmin.business.organization.service;

import cn.tqfeiyang.smartadmin.business.organization.entity.AddressEntity;
import cn.tqfeiyang.smartadmin.business.organization.mapper.AddressMapper;
import cn.tqfeiyang.smartadmin.business.organization.request.AddressCreateDTO;
import cn.tqfeiyang.smartadmin.business.organization.request.AddressUpdateDTO;
import cn.tqfeiyang.smartadmin.business.organization.request.AddressQueryDTO;
import cn.tqfeiyang.smartadmin.business.organization.response.AddressQueryVO;
import cn.tqfeiyang.smartadmin.business.organization.response.AddressDetailVO;

import com.github.pagehelper.PageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import jakarta.annotation.Resource;

import cn.tqfeiyang.smartadmin.commons.exception.BusinessException;
import cn.tqfeiyang.smartadmin.commons.toolbox.BeanUtils;
import cn.tqfeiyang.smartadmin.commons.pagination.PageData;
import cn.tqfeiyang.smartadmin.commons.mybatis.EntityBroadcast;
import cn.tqfeiyang.smartadmin.commons.toolbox.ValidationUtils;

import java.util.List;
import java.util.Objects;

/**
 * 地址CRUD服务
 *
 * @author tqfeiyang
 * @since 2024-10-18
 */
@Service
public class AddressCurdService {

    /**
     * 实体广播对象
     */
    @Resource
    private EntityBroadcast entityBroadcast;

    /**
     * 地址映射接口
     */
    @Resource
    private AddressMapper addressMapper;

    /**
     * 分页查询地址
     *
     * @param dto 请求数据
     * @return 地址分页
     */
    public PageData<AddressQueryVO> queryAddresses(AddressQueryDTO dto) {
        Assert.notNull(dto, "dto不能为空");
        ValidationUtils.validateProperties(dto);

        PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
        return PageData.create(addressMapper.queryAddresses(dto));
    }

    /**
     * 查询地址详情
     *
     * @param addressId 地址id
     * @return 地址详情
     */
    public AddressDetailVO readAddress(Long addressId) {
        Assert.notNull(addressId, "addressId不能为空");
        return addressMapper.readAddress(addressId);
    }

    /**
     * 添加地址
     *
     * @param dto 请求数据
     * @return 地址id
     */
    @Transactional(rollbackFor = Exception.class)
    public Long createAddress(AddressCreateDTO dto) {
        Assert.notNull(dto, "dto不能为空");
        ValidationUtils.validateProperties(dto);

        AddressEntity entity = BeanUtils.copy(dto, AddressEntity.class);
        entityBroadcast.validate(entity, true);

        addressMapper.insert(entity);
        entityBroadcast.clearCache(AddressEntity.class);
        return entity.getAddressId();
    }

    /**
     * 修改地址
     *
     * @param addressId 地址id
     * @param dto 请求数据
     * @return 地址id
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateAddress(Long addressId, AddressUpdateDTO dto) {
        Assert.notNull(addressId, "addressId不能为空");
        Assert.notNull(dto, "dto不能为空");
        ValidationUtils.validateProperties(dto);

        AddressEntity entity = addressMapper.selectById(addressId);
        if (Objects.isNull(entity)) {
            throw new BusinessException("地址id不存在({})", addressId);
        }

        entity = BeanUtils.copy(dto, AddressEntity.class);
        entity.setAddressId(addressId);
        entityBroadcast.validate(entity, false);

        addressMapper.updateById(entity);
        entityBroadcast.clearCache(AddressEntity.class);
    }

    /**
     * 删除地址
     *
     * @param addressId 地址id
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteAddress(Long addressId) {
        Assert.notNull(addressId, "addressId不能为空");

        AddressEntity entity = addressMapper.selectById(addressId);
        if (Objects.isNull(entity)) {
            throw new BusinessException("地址id不存在({})", addressId);
        }

        entityBroadcast.beforeDelete(entity);
        addressMapper.deleteAddress(addressId);
        entityBroadcast.afterDelete(entity);
        entityBroadcast.clearCache(AddressEntity.class);
    }

    /**
     * 批量删除地址
     *
     * @param addressIds 地址id列表
     */
    @Transactional(rollbackFor = Exception.class)
    public void batchDeleteAddresses(List<Long> addressIds) {
        Assert.notNull(addressIds, "addressIds不能为空");
        addressIds.forEach(addressId -> {
            AddressEntity entity = addressMapper.selectById(addressId);
            if (Objects.isNull(entity)) {
                throw new BusinessException("地址id不存在({})", addressId);
            }

            entityBroadcast.beforeDelete(entity);
            addressMapper.deleteAddress(addressId);
            entityBroadcast.afterDelete(entity);
        });
        entityBroadcast.clearCache(AddressEntity.class);
    }
}
